
<!DOCTYPE HTML>
<html lang="" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>Middleware · GitBook</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.2">
        
        
        
    
    <link rel="stylesheet" href="../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-highlight/website.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-search/search.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
    
        
    
        
    
        
    
        
    
        
    

        
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="UsageWithReactRouter.html" />
    
    
    <link rel="prev" href="AsyncFlow.html" />
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="Type to search" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../">
            
                <a href="../">
            
                    
                    Read Me
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" data-path="../introduction/">
            
                <a href="../introduction/">
            
                    
                    Introduction
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.2.1" data-path="../introduction/Motivation.html">
            
                <a href="../introduction/Motivation.html">
            
                    
                    Motivation
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.2" data-path="../introduction/CoreConcepts.html">
            
                <a href="../introduction/CoreConcepts.html">
            
                    
                    Core Concepts
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.3" data-path="../introduction/ThreePrinciples.html">
            
                <a href="../introduction/ThreePrinciples.html">
            
                    
                    Three Principles
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.4" data-path="../introduction/PriorArt.html">
            
                <a href="../introduction/PriorArt.html">
            
                    
                    Prior Art
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.5" data-path="../introduction/Ecosystem.html">
            
                <a href="../introduction/Ecosystem.html">
            
                    
                    Ecosystem
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.6" data-path="../introduction/Examples.html">
            
                <a href="../introduction/Examples.html">
            
                    
                    Examples
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.3" data-path="../basics/">
            
                <a href="../basics/">
            
                    
                    Basics
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.3.1" data-path="../basics/Actions.html">
            
                <a href="../basics/Actions.html">
            
                    
                    Actions
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.2" data-path="../basics/Reducers.html">
            
                <a href="../basics/Reducers.html">
            
                    
                    Reducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.3" data-path="../basics/Store.html">
            
                <a href="../basics/Store.html">
            
                    
                    Store
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.4" data-path="../basics/DataFlow.html">
            
                <a href="../basics/DataFlow.html">
            
                    
                    Data Flow
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.5" data-path="../basics/UsageWithReact.html">
            
                <a href="../basics/UsageWithReact.html">
            
                    
                    Usage with React
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.6" data-path="../basics/ExampleTodoList.html">
            
                <a href="../basics/ExampleTodoList.html">
            
                    
                    Example: Todo List
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4" data-path="./">
            
                <a href="./">
            
                    
                    Advanced
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.1" data-path="AsyncActions.html">
            
                <a href="AsyncActions.html">
            
                    
                    Async Actions
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.2" data-path="AsyncFlow.html">
            
                <a href="AsyncFlow.html">
            
                    
                    Async Flow
            
                </a>
            

            
        </li>
    
        <li class="chapter active" data-level="1.4.3" data-path="Middleware.html">
            
                <a href="Middleware.html">
            
                    
                    Middleware
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4" data-path="UsageWithReactRouter.html">
            
                <a href="UsageWithReactRouter.html">
            
                    
                    Usage with React Router
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.5" data-path="ExampleRedditAPI.html">
            
                <a href="ExampleRedditAPI.html">
            
                    
                    Example: Reddit API
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.6" >
            
                <span>
            
                    
                    Next Steps
            
                </span>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5" data-path="../recipes/">
            
                <a href="../recipes/">
            
                    
                    Recipes
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.1" data-path="../recipes/MigratingToRedux.html">
            
                <a href="../recipes/MigratingToRedux.html">
            
                    
                    Migrating to Redux
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.2" data-path="../recipes/UsingObjectSpreadOperator.html">
            
                <a href="../recipes/UsingObjectSpreadOperator.html">
            
                    
                    Using Object Spread Operator
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.3" data-path="../recipes/ReducingBoilerplate.html">
            
                <a href="../recipes/ReducingBoilerplate.html">
            
                    
                    Reducing Boilerplate
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.4" data-path="../recipes/ServerRendering.html">
            
                <a href="../recipes/ServerRendering.html">
            
                    
                    Server Rendering
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.5" data-path="../recipes/WritingTests.html">
            
                <a href="../recipes/WritingTests.html">
            
                    
                    Writing Tests
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.6" data-path="../recipes/ComputingDerivedData.html">
            
                <a href="../recipes/ComputingDerivedData.html">
            
                    
                    Computing Derived Data
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.7" data-path="../recipes/ImplementingUndoHistory.html">
            
                <a href="../recipes/ImplementingUndoHistory.html">
            
                    
                    Implementing Undo History
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8" data-path="../recipes/IsolatingSubapps.html">
            
                <a href="../recipes/IsolatingSubapps.html">
            
                    
                    Isolating Subapps
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9" data-path="../recipes/StructuringReducers.html">
            
                <a href="../recipes/StructuringReducers.html">
            
                    
                    Structuring Reducers
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.9.1" data-path="../recipes/reducers/PrerequisiteConcepts.html">
            
                <a href="../recipes/reducers/PrerequisiteConcepts.html">
            
                    
                    Prerequisite Concepts
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.2" data-path="../recipes/reducers/BasicReducerStructure.html">
            
                <a href="../recipes/reducers/BasicReducerStructure.html">
            
                    
                    Basic Reducer Structure
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.3" data-path="../recipes/reducers/SplittingReducerLogic.html">
            
                <a href="../recipes/reducers/SplittingReducerLogic.html">
            
                    
                    Splitting Reducer Logic
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.4" data-path="../recipes/reducers/RefactoringReducersExample.html">
            
                <a href="../recipes/reducers/RefactoringReducersExample.html">
            
                    
                    Refactoring Reducers Example
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.5" data-path="../recipes/reducers/UsingCombineReducers.html">
            
                <a href="../recipes/reducers/UsingCombineReducers.html">
            
                    
                    Using combineReducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.6" data-path="../recipes/reducers/BeyondCombineReducers.html">
            
                <a href="../recipes/reducers/BeyondCombineReducers.html">
            
                    
                    Beyond combineReducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.7" data-path="../recipes/reducers/NormalizingStateShape.html">
            
                <a href="../recipes/reducers/NormalizingStateShape.html">
            
                    
                    Normalizing State Shape
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.8" data-path="../recipes/reducers/UpdatingNormalizedData.html">
            
                <a href="../recipes/reducers/UpdatingNormalizedData.html">
            
                    
                    Updating Normalized Data
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.9" data-path="../recipes/reducers/ReusingReducerLogic.html">
            
                <a href="../recipes/reducers/ReusingReducerLogic.html">
            
                    
                    Reusing Reducer Logic
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.10" data-path="../recipes/reducers/ImmutableUpdatePatterns.html">
            
                <a href="../recipes/reducers/ImmutableUpdatePatterns.html">
            
                    
                    Immutable Update Patterns
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.11" data-path="../recipes/reducers/InitializingState.html">
            
                <a href="../recipes/reducers/InitializingState.html">
            
                    
                    Initializing State
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.10" data-path="../recipes/UsingImmutableJS.html">
            
                <a href="../recipes/UsingImmutableJS.html">
            
                    
                    Using Immutable.JS with Redux
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6" data-path="../FAQ.html">
            
                <a href="../FAQ.html">
            
                    
                    FAQ
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.1" data-path="../faq/General.html">
            
                <a href="../faq/General.html">
            
                    
                    General
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2" data-path="../faq/Reducers.html">
            
                <a href="../faq/Reducers.html">
            
                    
                    Reducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.3" data-path="../faq/OrganizingState.html">
            
                <a href="../faq/OrganizingState.html">
            
                    
                    Organizing State
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4" data-path="../faq/StoreSetup.html">
            
                <a href="../faq/StoreSetup.html">
            
                    
                    Store Setup
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.5" data-path="../faq/Actions.html">
            
                <a href="../faq/Actions.html">
            
                    
                    Actions
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6" data-path="../faq/ImmutableData.html">
            
                <a href="../faq/ImmutableData.html">
            
                    
                    Immutable Data
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.7" data-path="../faq/CodeStructure.html">
            
                <a href="../faq/CodeStructure.html">
            
                    
                    Code Structure
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8" data-path="../faq/Performance.html">
            
                <a href="../faq/Performance.html">
            
                    
                    Performance
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9" data-path="../faq/ReactRedux.html">
            
                <a href="../faq/ReactRedux.html">
            
                    
                    React Redux
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10" data-path="../faq/Miscellaneous.html">
            
                <a href="../faq/Miscellaneous.html">
            
                    
                    Miscellaneous
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7" data-path="../Troubleshooting.html">
            
                <a href="../Troubleshooting.html">
            
                    
                    Troubleshooting
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.8" data-path="../Glossary.html">
            
                <a href="../Glossary.html">
            
                    
                    Glossary
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9" data-path="../api/">
            
                <a href="../api/">
            
                    
                    API Reference
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.9.1" data-path="../api/createStore.html">
            
                <a href="../api/createStore.html">
            
                    
                    createStore
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.2" data-path="../api/Store.html">
            
                <a href="../api/Store.html">
            
                    
                    Store
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.3" data-path="../api/combineReducers.html">
            
                <a href="../api/combineReducers.html">
            
                    
                    combineReducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.4" data-path="../api/applyMiddleware.html">
            
                <a href="../api/applyMiddleware.html">
            
                    
                    applyMiddleware
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.5" data-path="../api/bindActionCreators.html">
            
                <a href="../api/bindActionCreators.html">
            
                    
                    bindActionCreators
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.6" data-path="../api/compose.html">
            
                <a href="../api/compose.html">
            
                    
                    compose
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.10" data-path="../CHANGELOG.md">
            
                <span>
            
                    
                    Change Log
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.11" data-path="../PATRONS.md">
            
                <span>
            
                    
                    Patrons
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.12" data-path="../Feedback.html">
            
                <a href="../Feedback.html">
            
                    
                    Feedback
            
                </a>
            

            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            Published with GitBook
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href=".." >Middleware</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <h1 id="middleware">Middleware</h1>
<p>You&apos;ve seen <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> in <a href="../Glossary.html#action" class="glossary-term" title="">action</a> in the <a href="AsyncActions.html">Async Actions</a> example. If you&apos;ve used server-side libraries like <a href="http://expressjs.com/" target="_blank">Express</a> and <a href="http://koajs.com/" target="_blank">Koa</a>, you were also probably already familiar with the concept of <em><a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a></em>. In these frameworks, <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> is some code you can put between the framework receiving a request, and the framework generating a response. For example, Express or Koa <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> may add CORS headers, logging, compression, and more. The best feature of <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> is that it&apos;s composable in a chain. You can use multiple independent third-party <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> in a single project.</p>
<p>Redux <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> solves different problems than Express or Koa <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>, but in a conceptually similar way. <strong>It provides a third-party extension point between dispatching an <a href="../Glossary.html#action" class="glossary-term" title="">action</a>, and the moment it reaches the <a href="../Glossary.html#reducer" class="glossary-term" title="">reducer</a>.</strong> People use Redux <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> for logging, crash reporting, talking to an asynchronous API, routing, and more.</p>
<p>This article is divided into an in-depth intro to help you grok the concept, and <a href="#seven-examples">a few practical examples</a> to show the power of <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> at the very end. You may find it helpful to switch back and forth between them, as you flip between feeling bored and inspired.</p>
<h2 id="understanding-middleware">Understanding Middleware</h2>
<p>While <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> can be used for a variety of things, including asynchronous API calls, it&apos;s really important that you understand where it comes from. We&apos;ll guide you through the thought process leading to <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>, by using logging and crash reporting as examples.</p>
<h3 id="problem-logging">Problem: Logging</h3>
<p>One of the benefits of Redux is that it makes <a href="../Glossary.html#state" class="glossary-term" title="">state</a> changes predictable and transparent. Every time an <a href="../Glossary.html#action" class="glossary-term" title="">action</a> is dispatched, the new <a href="../Glossary.html#state" class="glossary-term" title="">state</a> is computed and saved. The <a href="../Glossary.html#state" class="glossary-term" title="">state</a> cannot change by itself, it can only change as a consequence of a specific <a href="../Glossary.html#action" class="glossary-term" title="">action</a>.</p>
<p>Wouldn&apos;t it be nice if we logged every <a href="../Glossary.html#action" class="glossary-term" title="">action</a> that happens in the app, together with the <a href="../Glossary.html#state" class="glossary-term" title="">state</a> computed after it? When something goes wrong, we can look back at our log, and figure out which <a href="../Glossary.html#action" class="glossary-term" title="">action</a> corrupted the <a href="../Glossary.html#state" class="glossary-term" title="">state</a>.</p>
<p><img src="http://i.imgur.com/BjGBlES.png" width="70%"></p>
<p>How do we approach this with Redux?</p>
<h3 id="attempt-1-logging-manually">Attempt #1: Logging Manually</h3>
<p>The most na&#xEF;ve solution is just to log the <a href="../Glossary.html#action" class="glossary-term" title="">action</a> and the next <a href="../Glossary.html#state" class="glossary-term" title="">state</a> yourself every time you call <a href="../api/Store.html#dispatch"><code>store.dispatch(action)</code></a>. It&apos;s not really a solution, but just a first step towards understanding the problem.</p>
<blockquote>
<h5 id="note">Note</h5>
<p>If you&apos;re using <a href="https://github.com/gaearon/react-redux" target="_blank">react-redux</a> or similar bindings, you likely won&apos;t have direct access to the <a href="../Glossary.html#store" class="glossary-term" title="">store</a> instance in your components. For the next few paragraphs, just assume you pass the <a href="../Glossary.html#store" class="glossary-term" title="">store</a> down explicitly.</p>
</blockquote>
<p>Say, you call this when creating a todo:</p>
<pre><code class="lang-js">store.dispatch(addTodo(<span class="hljs-string">&apos;Use Redux&apos;</span>))
</code></pre>
<p>To log the <a href="../Glossary.html#action" class="glossary-term" title="">action</a> and <a href="../Glossary.html#state" class="glossary-term" title="">state</a>, you can change it to something like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> action = addTodo(<span class="hljs-string">&apos;Use Redux&apos;</span>)

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
store.dispatch(action)
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
</code></pre>
<p>This produces the desired effect, but you wouldn&apos;t want to do it every time.</p>
<h3 id="attempt-2-wrapping-dispatch">Attempt #2: Wrapping Dispatch</h3>
<p>You can extract logging into a function:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatchAndLog</span>(<span class="hljs-params">store, action</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
  store.dispatch(action)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
}
</code></pre>
<p>You can then use it everywhere instead of <code>store.dispatch()</code>:</p>
<pre><code class="lang-js">dispatchAndLog(store, addTodo(<span class="hljs-string">&apos;Use Redux&apos;</span>))
</code></pre>
<p>We could end this here, but it&apos;s not very convenient to import a special function every time.</p>
<h3 id="attempt-3-monkeypatching-dispatch">Attempt #3: Monkeypatching Dispatch</h3>
<p>What if we just replace the <code>dispatch</code> function on the <a href="../Glossary.html#store" class="glossary-term" title="">store</a> instance? The Redux <a href="../Glossary.html#store" class="glossary-term" title="">store</a> is just a plain object with <a href="../api/Store.html">a few methods</a>, and we&apos;re writing JavaScript, so we can just monkeypatch the <code>dispatch</code> implementation:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> next = store.dispatch
store.dispatch = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatchAndLog</span>(<span class="hljs-params">action</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
  <span class="hljs-keyword">let</span> result = next(action)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
  <span class="hljs-keyword">return</span> result
}
</code></pre>
<p>This is already closer to what we want!  No matter where we dispatch an <a href="../Glossary.html#action" class="glossary-term" title="">action</a>, it is guaranteed to be logged. Monkeypatching never feels right, but we can live with this for now.</p>
<h3 id="problem-crash-reporting">Problem: Crash Reporting</h3>
<p>What if we want to apply <strong>more than one</strong> such transformation to <code>dispatch</code>?</p>
<p>A different useful transformation that comes to my mind is reporting JavaScript errors in production. The global <code>window.onerror</code> event is not reliable because it doesn&apos;t provide stack information in some older browsers, which is crucial to understand why an error is happening.</p>
<p>Wouldn&apos;t it be useful if, any time an error is thrown as a result of dispatching an <a href="../Glossary.html#action" class="glossary-term" title="">action</a>, we would send it to a crash reporting service like <a href="https://getsentry.com/welcome/" target="_blank">Sentry</a> with the stack trace, the <a href="../Glossary.html#action" class="glossary-term" title="">action</a> that caused the error, and the current <a href="../Glossary.html#state" class="glossary-term" title="">state</a>? This way it&apos;s much easier to reproduce the error in development.</p>
<p>However, it is important that we keep logging and crash reporting separate. Ideally we want them to be different modules, potentially in different packages. Otherwise we can&apos;t have an ecosystem of such utilities. (Hint: we&apos;re slowly getting to what <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> is!)</p>
<p>If logging and crash reporting are separate utilities, they might look like this:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">patchStoreToAddLogging</span>(<span class="hljs-params">store</span>) </span>{
  <span class="hljs-keyword">let</span> next = store.dispatch
  store.dispatch = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatchAndLog</span>(<span class="hljs-params">action</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
    <span class="hljs-keyword">let</span> result = next(action)
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
    <span class="hljs-keyword">return</span> result
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">patchStoreToAddCrashReporting</span>(<span class="hljs-params">store</span>) </span>{
  <span class="hljs-keyword">let</span> next = store.dispatch
  store.dispatch = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatchAndReportErrors</span>(<span class="hljs-params">action</span>) </span>{
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">return</span> next(action)
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">&apos;Caught an exception!&apos;</span>, err)
      Raven.captureException(err, {
        extra: {
          action,
          state: store.getState()
        }
      })
      <span class="hljs-keyword">throw</span> err
    }
  }
}
</code></pre>
<p>If these functions are published as separate modules, we can later use them to patch our <a href="../Glossary.html#store" class="glossary-term" title="">store</a>:</p>
<pre><code class="lang-js">patchStoreToAddLogging(store)
patchStoreToAddCrashReporting(store)
</code></pre>
<p>Still, this isn&apos;t nice.</p>
<h3 id="attempt-4-hiding-monkeypatching">Attempt #4: Hiding Monkeypatching</h3>
<p>Monkeypatching is a hack. &#x201C;Replace any method you like&#x201D;, what kind of API is that? Let&apos;s figure out the essence of it instead. Previously, our functions replaced <code>store.dispatch</code>. What if they <em>returned</em> the new <code>dispatch</code> function instead?</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logger</span>(<span class="hljs-params">store</span>) </span>{
  <span class="hljs-keyword">let</span> next = store.dispatch

  <span class="hljs-comment">// Previously:</span>
  <span class="hljs-comment">// store.dispatch = function dispatchAndLog(action) {</span>

  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatchAndLog</span>(<span class="hljs-params">action</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
    <span class="hljs-keyword">let</span> result = next(action)
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
    <span class="hljs-keyword">return</span> result
  }
}
</code></pre>
<p>We could provide a helper inside Redux that would apply the actual monkeypatching as an implementation detail:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">applyMiddlewareByMonkeypatching</span>(<span class="hljs-params">store, middlewares</span>) </span>{
  middlewares = middlewares.slice()
  middlewares.reverse()

  <span class="hljs-comment">// Transform dispatch function with each middleware.</span>
  middlewares.forEach(middleware =&gt;
    store.dispatch = middleware(store)
  )
}
</code></pre>
<p>We could use it to apply multiple <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> like this:</p>
<pre><code class="lang-js">applyMiddlewareByMonkeypatching(store, [ logger, crashReporter ])
</code></pre>
<p>However, it is still monkeypatching.<br>The fact that we hide it inside the library doesn&apos;t alter this fact.</p>
<h3 id="attempt-5-removing-monkeypatching">Attempt #5: Removing Monkeypatching</h3>
<p>Why do we even overwrite <code>dispatch</code>? Of course, to be able to call it later, but there&apos;s also another reason: so that every <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> can access (and call) the previously wrapped <code>store.dispatch</code>:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logger</span>(<span class="hljs-params">store</span>) </span>{
  <span class="hljs-comment">// Must point to the function returned by the previous middleware:</span>
  <span class="hljs-keyword">let</span> next = store.dispatch

  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatchAndLog</span>(<span class="hljs-params">action</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
    <span class="hljs-keyword">let</span> result = next(action)
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
    <span class="hljs-keyword">return</span> result
  }
}
</code></pre>
<p>It is essential to chaining <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>!</p>
<p>If <code>applyMiddlewareByMonkeypatching</code> doesn&apos;t assign <code>store.dispatch</code> immediately after processing the first <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>, <code>store.dispatch</code> will keep pointing to the original <code>dispatch</code> function. Then the second <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> will also be bound to the original <code>dispatch</code> function.</p>
<p>But there&apos;s also a different way to enable chaining. The <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> could accept the <code>next()</code> dispatch function as a parameter instead of reading it from the <code>store</code> instance.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">logger</span>(<span class="hljs-params">store</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">wrapDispatchToAddLogging</span>(<span class="hljs-params">next</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dispatchAndLog</span>(<span class="hljs-params">action</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
      <span class="hljs-keyword">let</span> result = next(action)
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
      <span class="hljs-keyword">return</span> result
    }
  }
}
</code></pre>
<p>It&apos;s a <a href="http://knowyourmeme.com/memes/we-need-to-go-deeper" target="_blank">&#x201C;we need to go deeper&#x201D;</a> kind of moment, so it might take a while for this to make sense. The function cascade feels intimidating. ES6 arrow functions make this <a href="https://en.wikipedia.org/wiki/Currying" target="_blank">currying</a> easier on eyes:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> logger = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
  <span class="hljs-keyword">let</span> result = next(action)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
  <span class="hljs-keyword">return</span> result
}

<span class="hljs-keyword">const</span> crashReporter = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">return</span> next(action)
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">&apos;Caught an exception!&apos;</span>, err)
    Raven.captureException(err, {
      extra: {
        action,
        state: store.getState()
      }
    })
    <span class="hljs-keyword">throw</span> err
  }
}
</code></pre>
<p><strong>This is exactly what Redux <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> looks like.</strong></p>
<p>Now <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> takes the <code>next()</code> dispatch function, and returns a dispatch function, which in turn serves as <code>next()</code> to the <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> to the left, and so on. It&apos;s still useful to have access to some <a href="../Glossary.html#store" class="glossary-term" title="">store</a> methods like <code>getState()</code>, so <code>store</code> stays available as the top-level argument.</p>
<h3 id="attempt-6-na&#xEF;vely-applying-the-middleware">Attempt #6: Na&#xEF;vely Applying the Middleware</h3>
<p>Instead of <code>applyMiddlewareByMonkeypatching()</code>, we could write <code>applyMiddleware()</code> that first obtains the final, fully wrapped <code>dispatch()</code> function, and returns a copy of the <a href="../Glossary.html#store" class="glossary-term" title="">store</a> using it:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Warning: Na&#xEF;ve implementation!</span>
<span class="hljs-comment">// That&apos;s *not* Redux API.</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">applyMiddleware</span>(<span class="hljs-params">store, middlewares</span>) </span>{
  middlewares = middlewares.slice()
  middlewares.reverse()

  <span class="hljs-keyword">let</span> dispatch = store.dispatch
  middlewares.forEach(middleware =&gt;
    dispatch = middleware(store)(dispatch)
  )

  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.assign({}, store, { dispatch })
}
</code></pre>
<p>The implementation of <a href="../api/applyMiddleware.html"><code>applyMiddleware()</code></a> that ships with Redux is similar, but <strong>different in three important aspects</strong>:</p>
<ul>
<li><p>It only exposes a subset of the <a href="../api/Store.html">store API</a> to the <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>: <a href="../api/Store.html#dispatch"><code>dispatch(action)</code></a> and <a href="../api/Store.html#getState"><code>getState()</code></a>.</p>
</li>
<li><p>It does a bit of trickery to make sure that if you call <code>store.dispatch(action)</code> from your <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> instead of <code>next(action)</code>, the <a href="../Glossary.html#action" class="glossary-term" title="">action</a> will actually travel the whole <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> chain again, including the current <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>. This is useful for asynchronous <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>, as we have seen <a href="AsyncActions.html">previously</a>.</p>
</li>
<li><p>To ensure that you may only apply <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> once, it operates on <code>createStore()</code> rather than on <code>store</code> itself. Instead of <code>(store, middlewares) =&gt; store</code>, its signature is <code>(...middlewares) =&gt; (createStore) =&gt; createStore</code>.</p>
</li>
</ul>
<p>Because it is cumbersome to apply functions to <code>createStore()</code> before using it, <code>createStore()</code> accepts an optional last argument to specify such functions.</p>
<h3 id="the-final-approach">The Final Approach</h3>
<p>Given this <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> we just wrote:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> logger = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
  <span class="hljs-keyword">let</span> result = next(action)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
  <span class="hljs-keyword">return</span> result
}

<span class="hljs-keyword">const</span> crashReporter = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">return</span> next(action)
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">&apos;Caught an exception!&apos;</span>, err)
    Raven.captureException(err, {
      extra: {
        action,
        state: store.getState()
      }
    })
    <span class="hljs-keyword">throw</span> err
  }
}
</code></pre>
<p>Here&apos;s how to apply it to a Redux <a href="../Glossary.html#store" class="glossary-term" title="">store</a>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { createStore, combineReducers, applyMiddleware } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;redux&apos;</span>

<span class="hljs-keyword">let</span> todoApp = combineReducers(reducers)
<span class="hljs-keyword">let</span> store = createStore(
  todoApp,
  <span class="hljs-comment">// applyMiddleware() tells createStore() how to handle middleware</span>
  applyMiddleware(logger, crashReporter)
)
</code></pre>
<p>That&apos;s it! Now any actions dispatched to the <a href="../Glossary.html#store" class="glossary-term" title="">store</a> instance will flow through <code>logger</code> and <code>crashReporter</code>:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Will flow through both logger and crashReporter middleware!</span>
store.dispatch(addTodo(<span class="hljs-string">&apos;Use Redux&apos;</span>))
</code></pre>
<h2 id="seven-examples">Seven Examples</h2>
<p>If your head boiled from reading the above section, imagine what it was like to write it. This section is meant to be a relaxation for you and me, and will help get your gears turning.</p>
<p>Each function below is a valid Redux <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>. They are not equally useful, but at least they are equally fun.</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * Logs all actions and states after they are dispatched.
 */</span>
<span class="hljs-keyword">const</span> logger = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-built_in">console</span>.group(action.type)
  <span class="hljs-built_in">console</span>.info(<span class="hljs-string">&apos;dispatching&apos;</span>, action)
  <span class="hljs-keyword">let</span> result = next(action)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&apos;next state&apos;</span>, store.getState())
  <span class="hljs-built_in">console</span>.groupEnd(action.type)
  <span class="hljs-keyword">return</span> result
}

<span class="hljs-comment">/**
 * Sends crash reports as state is updated and listeners are notified.
 */</span>
<span class="hljs-keyword">const</span> crashReporter = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">return</span> next(action)
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">&apos;Caught an exception!&apos;</span>, err)
    Raven.captureException(err, {
      extra: {
        action,
        state: store.getState()
      }
    })
    <span class="hljs-keyword">throw</span> err
  }
}

<span class="hljs-comment">/**
 * Schedules actions with { meta: { delay: N } } to be delayed by N milliseconds.
 * Makes `dispatch` return a function to cancel the timeout in this case.
 */</span>
<span class="hljs-keyword">const</span> timeoutScheduler = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-keyword">if</span> (!action.meta || !action.meta.delay) {
    <span class="hljs-keyword">return</span> next(action)
  }

  <span class="hljs-keyword">let</span> timeoutId = setTimeout(
    () =&gt; next(action),
    action.meta.delay
  )

  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cancel</span>(<span class="hljs-params"></span>) </span>{
    clearTimeout(timeoutId)
  }
}

<span class="hljs-comment">/**
 * Schedules actions with { meta: { raf: true } } to be dispatched inside a rAF loop
 * frame.  Makes `dispatch` return a function to remove the action from the queue in
 * this case.
 */</span>
<span class="hljs-keyword">const</span> rafScheduler = store =&gt; next =&gt; {
  <span class="hljs-keyword">let</span> queuedActions = []
  <span class="hljs-keyword">let</span> frame = <span class="hljs-literal">null</span>

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loop</span>(<span class="hljs-params"></span>) </span>{
    frame = <span class="hljs-literal">null</span>
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">if</span> (queuedActions.length) {
        next(queuedActions.shift())
      }
    } <span class="hljs-keyword">finally</span> {
      maybeRaf()
    }
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">maybeRaf</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">if</span> (queuedActions.length &amp;&amp; !frame) {
      frame = requestAnimationFrame(loop)
    }
  }

  <span class="hljs-keyword">return</span> action =&gt; {
    <span class="hljs-keyword">if</span> (!action.meta || !action.meta.raf) {
      <span class="hljs-keyword">return</span> next(action)
    }

    queuedActions.push(action)
    maybeRaf()

    <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cancel</span>(<span class="hljs-params"></span>) </span>{
      queuedActions = queuedActions.filter(a =&gt; a !== action)
    }
  }
}

<span class="hljs-comment">/**
 * Lets you dispatch promises in addition to actions.
 * If the promise is resolved, its result will be dispatched as an action.
 * The promise is returned from `dispatch` so the caller may handle rejection.
 */</span>
<span class="hljs-keyword">const</span> vanillaPromise = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> action.then !== <span class="hljs-string">&apos;function&apos;</span>) {
    <span class="hljs-keyword">return</span> next(action)
  }

  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.resolve(action).then(store.dispatch)
}

<span class="hljs-comment">/**
 * Lets you dispatch special actions with a { promise } field.
 *
 * This middleware will turn them into a single action at the beginning,
 * and a single success (or failure) action when the `promise` resolves.
 *
 * For convenience, `dispatch` will return the promise so the caller can wait.
 */</span>
<span class="hljs-keyword">const</span> readyStatePromise = store =&gt; next =&gt; action =&gt; {
  <span class="hljs-keyword">if</span> (!action.promise) {
    <span class="hljs-keyword">return</span> next(action)
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makeAction</span>(<span class="hljs-params">ready, data</span>) </span>{
    <span class="hljs-keyword">let</span> newAction = <span class="hljs-built_in">Object</span>.assign({}, action, { ready }, data)
    <span class="hljs-keyword">delete</span> newAction.promise
    <span class="hljs-keyword">return</span> newAction
  }

  next(makeAction(<span class="hljs-literal">false</span>))
  <span class="hljs-keyword">return</span> action.promise.then(
    result =&gt; next(makeAction(<span class="hljs-literal">true</span>, { result })),
    error =&gt; next(makeAction(<span class="hljs-literal">true</span>, { error }))
  )
}

<span class="hljs-comment">/**
 * Lets you dispatch a function instead of an action.
 * This function will receive `dispatch` and `getState` as arguments.
 *
 * Useful for early exits (conditions over `getState()`), as well
 * as for async control flow (it can `dispatch()` something else).
 *
 * `dispatch` will return the return value of the dispatched function.
 */</span>
<span class="hljs-keyword">const</span> thunk = store =&gt; next =&gt; action =&gt;
  <span class="hljs-keyword">typeof</span> action === <span class="hljs-string">&apos;function&apos;</span> ?
    action(store.dispatch, store.getState) :
    next(action)


<span class="hljs-comment">// You can use all of them! (It doesn&apos;t mean you should.)</span>
<span class="hljs-keyword">let</span> todoApp = combineReducers(reducers)
<span class="hljs-keyword">let</span> store = createStore(
  todoApp,
  applyMiddleware(
    rafScheduler,
    timeoutScheduler,
    thunk,
    vanillaPromise,
    readyStatePromise,
    logger,
    crashReporter
  )
)
</code></pre>

                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="AsyncFlow.html" class="navigation navigation-prev " aria-label="Previous page: Async Flow">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="UsageWithReactRouter.html" class="navigation navigation-next " aria-label="Next page: Usage with React Router">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"Middleware","level":"1.4.3","depth":2,"next":{"title":"Usage with React Router","level":"1.4.4","depth":2,"path":"advanced/UsageWithReactRouter.md","ref":"./advanced/UsageWithReactRouter.md","articles":[]},"previous":{"title":"Async Flow","level":"1.4.2","depth":2,"path":"advanced/AsyncFlow.md","ref":"./advanced/AsyncFlow.md","articles":[]},"dir":"ltr"},"config":{"gitbook":"*","theme":"default","variables":{},"plugins":["livereload"],"pluginsConfig":{"livereload":{},"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"}},"file":{"path":"advanced/Middleware.md","mtime":"2017-03-13T14:28:11.282Z","type":"markdown"},"gitbook":{"version":"3.2.2","time":"2017-03-15T14:47:19.389Z"},"basePath":"..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../gitbook/gitbook.js"></script>
    <script src="../gitbook/theme.js"></script>
    
        
        <script src="../gitbook/gitbook-plugin-livereload/plugin.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search/search-engine.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search/search.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

